/**
 * MP Software.
 */
package service;

import java.math.BigDecimal;
import java.util.List;

import models.Deduction;
import models.Payment;
import models.Rate;

/**
 * @author Jeremiah John M. Macariola
 *
 */
public abstract class AbstractPayrollCalculator implements PayrollCalculator {

    public CalculationResult calculate(Rate rate, List<Payment> payments,
            List<Deduction> deductions) {
        CalculationResult result = new CalculationResult();

        /*
         * Calculate gross income.
         */
        result.grossIncome = calculateGrossIncome(rate, payments);

        /*
         * Calculate total deduction.
         */
        result.totalDeduction = calculateTotalDeduction(deductions);

        /*
         * Calculate net pay.
         */
        result.netPay = calculateNetPay(result.grossIncome,
                result.totalDeduction);

        return result;
    }

    protected BigDecimal calculateGrossIncome(Rate rate, List<Payment> payments) {
        BigDecimal grossIncome = BigDecimal.valueOf(0.00);

        for (Payment payment : payments) {
            BigDecimal paymentCalculation = calculatePayment(rate, payment);

            if (paymentCalculation != null) {
                grossIncome = grossIncome.add(paymentCalculation);
            }
        }

        return grossIncome;
    }

    protected BigDecimal calculateTotalDeduction(List<Deduction> deductions) {
        BigDecimal totalDeduction = BigDecimal.valueOf(0.00);

        for (Deduction deduction : deductions) {
            totalDeduction = totalDeduction.add(deduction.value);
        }

        return totalDeduction;
    }

    protected BigDecimal calculateNetPay(BigDecimal grossIncome,
            BigDecimal totalDeduction) {
        return grossIncome.subtract(totalDeduction);
    }

}
